home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / ast_comp / gopher.lha / gopher1.01 / gopherd / index.c < prev    next >
C/C++ Source or Header  |  1992-06-23  |  9KB  |  419 lines

  1. #include "gopherd.h"
  2. #include <stdio.h>
  3.  
  4. #define WAISTYPE 1
  5. #define NEXTTYPE 2
  6. #define SHLLTYPE 3
  7. #define GREPTYPE 4
  8.  
  9.  
  10. void 
  11. Do_IndexTrans(sockfd, inputline)
  12.   int sockfd;
  13.   char *inputline;
  14. {
  15.      char *IndexDirectory = NULL;
  16.      char *SearchString = NULL;
  17.      char *cp = NULL;
  18.      char *dbName = NULL;
  19.      char INDEXHost[256], INDEXPath[256];  /** Hard coded limits, ugh! **/
  20.      int  INDEXPort=0;
  21.      char logline[256];
  22.      int  Index_type=0;
  23.  
  24.      /** First siphon off the directory pathname **/
  25.      IndexDirectory = inputline;
  26.  
  27.      if (UsingHTML)
  28.       cp = strchr(inputline, '?');
  29.      else
  30.       cp = strchr(inputline, '\t');
  31.      
  32.      if (cp == NULL) {
  33.       if (UsingHTML) {
  34.            Index_type = Find_index_type(IndexDirectory);
  35.  
  36.            if (Index_type == -1) {
  37.             writestring(sockfd, "Server error....<P>\r\n");
  38.             writestring(sockfd, inputline);
  39.             writestring(sockfd, " is not a valid index<P>\r\n");
  40.             return;
  41.            }
  42.            writestring(sockfd, "<ISINDEX>\r\n");
  43.            writestring(sockfd, "This is a gopher index of ");
  44.            writestring(sockfd, inputline+1);
  45.            writestring(sockfd, ". <P>This is a ");
  46.            switch (Index_type) {
  47.            case WAISTYPE:
  48.             writestring(sockfd, "WAIS index\r\n");
  49.             break;
  50.            case NEXTTYPE:
  51.             writestring(sockfd, "NeXT Digital Librarian index\r\n");
  52.             break;
  53.            case GREPTYPE:
  54.             writestring(sockfd, "Brute force search of items in this directory\r\n");
  55.             break;
  56.            case SHLLTYPE:
  57.             writestring(sockfd, "strange gateway search\r\n");
  58.             break;
  59.            } 
  60.            writestring(sockfd, "<P>\r\n");
  61.            return;
  62.  
  63.       } else {
  64.            /** Give up it won't work..... **/
  65.            writestring(sockfd, ".\r\n");
  66.            return;
  67.       } 
  68.      }
  69.      else
  70.       *cp = '\0';
  71.  
  72.      
  73.      /** And siphon off the search string **/
  74.  
  75.      SearchString = cp +1;
  76.  
  77.      /** Just in case, get rid of anything following a tab **/
  78.  
  79.      cp = strchr(SearchString, '\t');
  80.      if (cp != NULL)
  81.       *cp = '\0';
  82.  
  83.  
  84.      Index_type = Find_index_type(IndexDirectory);
  85.  
  86.      if (DEBUG) 
  87.       printf("Index type is %d\n", Index_type);
  88.  
  89.      if (Index_type < 0) {
  90.       /**** Error condition, unknown index type... ****/
  91.       Abortoutput(sockfd, "Unknown index type");
  92.       return;
  93.      }
  94.       
  95.      if (Index_type == WAISTYPE) {
  96.       /*** The selector string has both the directory and the dbname... ***/
  97.       cp = strrchr(IndexDirectory, '/');
  98.       
  99.       if (cp == NULL)
  100.            dbName = "index";
  101.       else {
  102.            dbName= cp+1;
  103.            *cp='\0';
  104.       }
  105.      }
  106.  
  107.      if (Read_hostdata(IndexDirectory, INDEXHost, &INDEXPort, INDEXPath, dbName) <0) {
  108.       LOGGopher(sockfd, "Malformed hostdata file\n");
  109.       writestring(sockfd, "0Error on server, malformed hostdata\t\t\t1\r\n.\r\n");
  110.       return;
  111.      }
  112.      
  113.      /* Doctor up the indexdirectory path if we're not running chroot()
  114.       * we use fixfile to keep things secure....
  115.       */
  116.  
  117.      if (!dochroot) {
  118.       IndexDirectory = fixfile(IndexDirectory);
  119.       
  120.       cp = (char *) malloc(250);
  121.       strcpy(cp, Data_Dir);
  122.       strcat(cp, "/");
  123.       strcat(cp, IndexDirectory);
  124.  
  125.       IndexDirectory = cp;
  126.      }
  127.  
  128.  
  129.      /** And call the appropriate query function **/
  130.  
  131.      switch (Index_type) {
  132.  
  133.      case NEXTTYPE:
  134.       
  135.       NeXTIndexQuery(sockfd, SearchString, IndexDirectory, NULL, 
  136.              INDEXHost, INDEXPort);
  137.       break;
  138.  
  139.      case WAISTYPE:
  140.       WaisIndexQuery(sockfd, IndexDirectory, SearchString, dbName, 
  141.              INDEXHost, INDEXPort, INDEXPath);
  142.       break;
  143.  
  144.      case GREPTYPE:
  145.       GrepIndexQuery(sockfd, IndexDirectory, SearchString, 
  146.              INDEXHost, INDEXPort, INDEXPath);
  147.       break;
  148.       
  149.      case SHLLTYPE:
  150.       ShellIndexQuery(sockfd, IndexDirectory, SearchString);
  151.       break;
  152.      }
  153.      
  154.      /** Log it here so we get the query in the logfile **/
  155.  
  156.      if (dbName)
  157.       sprintf(logline, "search %s/%s for %s", IndexDirectory,
  158.           dbName, SearchString);
  159.      else
  160.       sprintf(logline, "search %s for %s", IndexDirectory, SearchString);
  161.  
  162.      LOGGopher(sockfd, logline);
  163. }
  164.  
  165.  
  166.  
  167. /*
  168.  * Try to figure out what each type of object is
  169.  *
  170.  * index types are 
  171.  *   Error       == -1
  172.  *   WAIS        == 1
  173.  *   NeXT        == 2
  174.  *   ShellScript == 3
  175.  *   Grep        == 4
  176.  */
  177.  
  178. int
  179. Find_index_type(gopherpath)
  180.   char *gopherpath;
  181. {
  182.      char Teststr[512];
  183.      FILE *Testfile;
  184.  
  185.      strcpy(Teststr, gopherpath);
  186.      strcat(Teststr, "/.index/index.ixif");
  187.  
  188.      Testfile = rfopen(Teststr, "r");
  189.      if (Testfile != NULL) {
  190.       /*** Next Index ***/
  191.       fclose(Testfile);
  192.       return(NEXTTYPE);
  193.      }
  194.  
  195.  
  196.      strcpy(Teststr, gopherpath);
  197.      strcat(Teststr, ".inv");
  198.  
  199.      Testfile = rfopen(Teststr, "r");
  200.      if (Testfile != NULL) {
  201.       /*** WAIS Index ***/
  202.       fclose(Testfile);
  203.       return(WAISTYPE);
  204.      }
  205.  
  206.  
  207.      strcpy(Teststr, gopherpath);
  208.  
  209.      if (isadir(Teststr) == 1) {
  210.       return(GREPTYPE);
  211.      }
  212.      
  213.      Testfile = rfopen(Teststr, "r");
  214.      if (Testfile != NULL) {
  215.       /** Shell script? **/
  216.       if (getc(Testfile) == '#')
  217.            if (getc(Testfile) == '!') {
  218.             fclose(Testfile);
  219.             return(SHLLTYPE);
  220.            }
  221.      }
  222.  
  223.      return(-1);
  224. }
  225.      
  226.  
  227. /*
  228.  * Read in the data from a hostdata file...
  229.  * 
  230.  * Try "<dbname>.hostdata" first, fall back to "hostdata" otherwise
  231.  */
  232.  
  233. int
  234. Read_hostdata(IndexDirectory, INDEXHost, INDEXPort, INDEXPath, dbName)
  235.   char *IndexDirectory;
  236.   char *INDEXHost, *INDEXPath;
  237.   int  *INDEXPort;
  238.   char *dbName;
  239. {
  240.      FILE *Hostfile;
  241.      char hostdataName[256];
  242.  
  243.      /** Read in the proper hostdata file.... **/
  244.  
  245.      rchdir(IndexDirectory);  /** Change into the index directory **/
  246.  
  247.      sprintf(hostdataName, "%s.hostdata", dbName);  /* try idx.hostdata */
  248.      if ((Hostfile = ufopen(hostdataName, "r")) == NULL)
  249.       Hostfile = ufopen("hostdata", "r");
  250.  
  251.      if (Hostfile == NULL) {
  252.       /*** Use the current host/port as the default ***/
  253.       fclose(Hostfile);
  254.       strcpy(INDEXHost, Zehostname);
  255.       *INDEXPort = GopherPort;
  256.       strcpy(INDEXPath, Data_Dir);
  257.      } 
  258.      else {
  259.       char tempbuf[255];
  260.  
  261.       if (fgets(INDEXHost, 64, Hostfile) == NULL)
  262.            return(-1);
  263.       
  264.       ZapCRLF(INDEXHost);
  265.       
  266.       if (fgets(tempbuf, 255, Hostfile) == NULL)
  267.            return(-1);
  268.       
  269.       if ((*INDEXPort=atoi(tempbuf))==0)
  270.            return(-1);
  271.       
  272.       if (fgets(INDEXPath, 256, Hostfile) == NULL)
  273.            return(-1);
  274.       
  275.       ZapCRLF(INDEXPath);
  276.       fclose(Hostfile);
  277.      }
  278.      
  279.      return(0);
  280. }
  281.  
  282.  
  283. /*
  284.  * This is a searching function that runs grep across files
  285.  * in a single directory...
  286.  */
  287.  
  288. GrepIndexQuery(sockfd, Indexdir, Searchstr, INDEXHost, INDEXPort, INDEXPath)
  289.   int sockfd;
  290.   char *Indexdir;
  291.   char *Searchstr;
  292.   char *INDEXHost;
  293.   int INDEXPort;
  294.   char *INDEXPath;
  295. {
  296.      FILE *moocow;
  297.      char command[512];
  298.      char inputline[512];
  299.      char outline[512];
  300.      char *cp;
  301.      GopherObj *gs;
  302.      GopherDirObj *gd;
  303.  
  304.      gs = GSnew();
  305.      gd = GDnew(32);
  306.  
  307.      sprintf(command, "egrep \"%s\" \"%s\"/*", Searchstr, Indexdir);
  308.      if (DEBUG) 
  309.       printf("Grep command is %s\n", command);
  310.  
  311.      moocow = popen(command, "r");
  312.      
  313.      if (moocow == NULL) {
  314.       writestring(sockfd, ".\r\n");
  315.       LOGGopher(sockfd, "Couldn't open grep command");
  316.       return;
  317.      }
  318.  
  319.      while (fgets(inputline, 512, moocow)) {
  320.       ZapCRLF(inputline);
  321.       GSsetType(gs, '0');
  322.  
  323.       cp = strstr(inputline, INDEXPath) + strlen(INDEXPath);
  324.       GSsetTitle(gs, cp);
  325.  
  326.       cp = strchr(inputline, ':');
  327.       *cp='\0';
  328.       cp =strstr(inputline, INDEXPath) + strlen(INDEXPath);
  329.       GSsetPath(gs, cp);
  330.       GSsetHost(gs, INDEXHost);
  331.       GSsetPort(gs, INDEXPort);
  332.  
  333.       GDaddGS(gd, gs);
  334.      }
  335.      if (UsingHTML)
  336.       GDtoNetHTML(gd, sockfd);
  337.      else {
  338.       GDtoNet(gd, sockfd);
  339.       writestring(sockfd, ".\r\n");
  340.      }
  341.  
  342.      pclose(moocow);
  343. }
  344.  
  345.  
  346.  
  347. /*
  348.  * This starts up a shell script that's defined to be an index gateway
  349.  * 
  350.  * The shell script should write out standard gopher directory protocol.
  351.  */
  352.  
  353. ShellIndexQuery(sockfd, Script, Searchstring)
  354.   int sockfd;
  355.   char *Script;
  356.   char *Searchstring;
  357. {
  358.      GopherDirObj *gd;
  359.      char Command[512];
  360.      FILE  *Searchprocess;
  361.      char inputline[512];
  362.      
  363.  
  364.      gd = GDnew(32);
  365.  
  366.      sprintf(Command, "\"%s\" \"%s\"", Script, Searchstring);
  367.  
  368.      Searchprocess = popen(Command, "r");
  369.  
  370.      if (Searchprocess == NULL) {
  371.       writestring(sockfd, ".\r\n");
  372.       return;
  373.      }
  374.  
  375.      GDfromNet(gd, fileno(Searchprocess), NULL);
  376.      if (UsingHTML)
  377.       GDtoNetHTML(gd, sockfd);
  378.      else {
  379.       GDtoNet(gd, sockfd);
  380.       writestring(sockfd, ".\r\n");
  381.      }
  382.  
  383.      pclose(Searchprocess);
  384.      GDdestroy(gd);
  385. }
  386.       
  387. #ifndef WAISSEARCH
  388.  
  389.  
  390. void
  391. WaisIndexQuery(sockfd, index_directory, SearchWords, new_db_name, INDEXHost, INDEXPort, INDEXPath)
  392.   int sockfd;
  393.   char *index_directory;
  394.   char *SearchWords;
  395.   char *new_db_name;
  396.   char *INDEXHost;
  397.   int  INDEXPort;
  398.   char *INDEXPath;
  399. {
  400.      Abortoutput(sockfd, "Sorry, this isn't a WAIS index...");
  401.      return;
  402. }
  403. #endif 
  404.  
  405. #ifndef NEXTSEARCH
  406. void
  407. NeXTIndexQuery(sockfd, SearchWords, ZIndexDirectory, DatabaseNm, INDEXHost, INDEXPort)
  408.   int sockfd;
  409.   char *SearchWords;
  410.   char *ZIndexDirectory;
  411.   char *DatabaseNm;  /*** Not used by the next indexer... ***/
  412.   char *INDEXHost;
  413.   int INDEXPort;
  414. {
  415.      Abortoutput(sockfd, "This isn't a NeXT... is it?");
  416.      return;
  417. }
  418. #endif
  419.